from abc import ABC, abstractmethod
from typing import ClassVar, Dict, Type, List

from implement.run_command.DefaultExecutor import DefaultExecutor
from interface.run_command_interfaces import ExecutorInterface


class ExecutorFactory(ABC):
    """执行器工厂抽象基类"""

    @abstractmethod
    def create_executor(self) -> ExecutorInterface:
        """创建执行器实例"""
        pass

    @classmethod
    @abstractmethod
    def is_available(cls, name: str) -> bool:
        """检查该工厂是否可用"""
        pass


class ExecutorFactoryRegistry:
    """执行器工厂注册中心（单例模式）"""
    _instance: ClassVar = None
    _factories: Dict[str, Type[ExecutorFactory]] = {}

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._initialize_default_factories()
        return cls._instance

    @classmethod
    def _initialize_default_factories(cls):
        """初始化默认工厂"""
        cls.register_factory('default', DefaultExecutorFactory)

    @classmethod
    def register_factory(cls, name: str, factory: Type[ExecutorFactory]):
        """注册新的工厂类型"""
        if not issubclass(factory, ExecutorFactory):
            raise TypeError("Factory must be a subclass of ExecutorFactory")
        cls._factories[name.lower()] = factory

    @classmethod
    def unregister_factory(cls, name: str):
        """取消注册工厂类型"""
        cls._factories.pop(name.lower(), None)

    @classmethod
    def get_factory_class(cls, name: str) -> Type[ExecutorFactory]:
        """根据名称获取工厂类"""
        return cls._factories.get(name.lower())

    @classmethod
    def get_available_factories(cls) -> List[Type[ExecutorFactory]]:
        """获取所有已注册的工厂类型"""
        return list(cls._factories.values())


class DefaultExecutorFactory(ExecutorFactory):
    @classmethod
    def is_available(cls, name: str) -> bool:
        return name.lower() == "default"

    def create_executor(self) -> ExecutorInterface:
        return DefaultExecutor()


class ExecutorFactorySelector:
    """工厂选择器"""

    @classmethod
    def select_factory(cls, name: str) -> ExecutorFactory:
        registry = ExecutorFactoryRegistry()
        factory_class = registry.get_factory_class(name)
        if factory_class and factory_class.is_available(name):
            return factory_class()
        raise ValueError(f"No available factory found for: {name}")


class ExecutorProvider:
    """执行器提供者 - 对外接口"""

    def __init__(self, name: str = "default"):
        self._factory = ExecutorFactorySelector.select_factory(name)

    def get_executor(self) -> ExecutorInterface:
        """获取执行器实例"""
        return self._factory.create_executor()

    def __str__(self):
        return f"{self.__class__.__name__} [Using: {type(self._factory).__name__}]"


if __name__ == '__main__':
    provider = ExecutorProvider("default")
    executor = provider.get_executor()
    print(executor)
